package com.yt.app.api.action.pay;

import com.alibaba.fastjson.JSONObject;
import com.yt.app.api.action.base.BaseAction;
import com.yt.app.api.action.pay.util.PayCommonUtil;
import com.yt.app.core.interfaces.UserOrderDetailService;
import com.yt.app.core.interfaces.UserOrderPayLogService;
import com.yt.app.core.interfaces.UserOrderService;
import com.yt.app.core.model.UserOrder;
import com.yt.app.core.model.UserOrderPayLog;
import com.yt.app.core.utils.Constant;
import com.yt.core.MsgBean;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.*;


/**
 * Description
 * <p>
 * 支付宝支付接口
 * </p>
 * DATE 2017/10/8.
 *
 * @author liujunshi.
 */

@Controller
@Api(tags = "11.支付")
@RequestMapping("/pay/wechat")
public class WechatNotifyController extends BaseAction{
    @Autowired
    private UserOrderService userOrderService;

    @Autowired
    private UserOrderDetailService userOrderDetailService;

    @Autowired
    private UserOrderPayLogService payLogService;

    @ApiOperation(value = "微信-异步通知", notes = "客户端不需要调用", httpMethod = "POST")
    @RequestMapping("/notify")
    public void notify(
            @ApiIgnore HttpServletRequest request,
            @ApiIgnore HttpServletResponse response
    ) {

        MsgBean msgBean = new MsgBean();
        Map<Object, Object> paramMap = null;
        UserOrder userOrder = null;
        try {
            InputStream inStream = request.getInputStream();
            ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = inStream.read(buffer)) != -1) {
                outSteam.write(buffer, 0, len);
            }
            outSteam.close();
            inStream.close();
            String result = new String(outSteam.toByteArray(), "utf-8");// 获取微信调用我们notify_url的返回信息
            paramMap = PayCommonUtil.doXMLParse(result);


            if (paramMap != null && paramMap.containsKey("result_code")
                    && paramMap.get("result_code").toString().equalsIgnoreCase("SUCCESS")) {
                if (verifyWeixinNotify(paramMap)) {
                    Object orderNo = paramMap.get("out_trade_no");
                    if (orderNo != null) {
                        userOrder = userOrderService.getByOrderNo(orderNo.toString());
                        userOrder.setPayType(Constant.PAY_TYPE.WECHAT.value() + "");
                        userOrder.setOrderStatus(Constant.ORDER_STATUS.PAID.value());
                        userOrderService.update(userOrder);
                        //订单处理
                        output(response, PayCommonUtil.setXML("SUCCESS", "OK"));
                        return;
                    }
                }
            }
        } catch (Exception ex) {
            output(response, PayCommonUtil.setXML("FAIL", "FAIL"));
            return;
        } finally {
            addPayLog(userOrder, paramMap);
        }
    }

    public boolean verifyWeixinNotify(Map<Object, Object> map) {
        SortedMap<String, Object> parameterMap = new TreeMap<String, Object>();
        String sign = (String) map.get("sign");
        for (Object keyValue : map.keySet()) {
            if (!keyValue.toString().equals("sign")) {
                parameterMap.put(keyValue.toString(), map.get(keyValue));
            }
        }
        String createSign = PayCommonUtil.createSign("UTF-8", parameterMap);
        if (createSign.equals(sign)) {
            return true;
        } else {
            return false;
        }

    }

    private void addPayLog(UserOrder userOrder, Map params) {
        try {
            UserOrderPayLog log = new UserOrderPayLog();
            log.setOrderNo(userOrder != null ? userOrder.getOrderNo() : "");
            log.setUid(userOrder != null ? userOrder.getUid() : 0l);
            log.setContent(JSONObject.toJSON(params).toString());
            log.setCreateDate(System.currentTimeMillis() / 1000);
            payLogService.insert(log);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}
